/*
* ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
* Without permission, no one has the right to obtain, disclose or use this software in any way.
*/

package ecarx.xsf.notificationcenter.manager;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;


import ecarx.xsf.notificationcenter.LauncherControllerApp;
import ecarx.xsf.notificationcenter.common.Constants;
import ecarx.xsf.notificationcenter.notification.ICardNotificationListener;
import ecarx.xsf.notificationcenter.notification.INotificationBar;
import ecarx.xsf.notificationcenter.push.PushMsgParser;
import ecarx.xsf.notificationcenter.scenecard.ISceneCardInfoV2;
import ecarx.xsf.notificationcenter.scenecard.ISceneCardListener;
import ecarx.xsf.notificationcenter.scenecard.ISceneCardListenerV2;
import ecarx.xsf.notificationcenter.sdk.IStatusBarNotification;

import java.util.ArrayList;
import java.util.List;

/**
 * FileName: NotificationDispatchManager.java <br>
 * Description : 消息队列数据分发 <br>
 * Create Time: 2020/03/16 11:32 <br>
 * Update Time: 2021/8/4 11:32 <br>
 *
 * @since 1.0.0
 */
public class NotificationDispatchManager {

    private static final String TAG = "NotificationDispatch";
    private static final int DISPATCH_NOTIFICATION = 1;
    private static final int CANCEL_NOTIFICATION = 2;


    private static final int DISPATCH_SCENE_CARD = 7;
    private static final int CANCEL_SCENE_CARD = 8;


    public static final int MSG_ERROR = -1;
    public static final int MSG_OK = 1;

    private List<ICardNotificationListener> mCallbackList;
    private List<ISceneCardListener> sceneCardCallbacks;
    private List<ISceneCardListenerV2> sceneCardCallbacksV2;


    private final Handler handler;

    public static final class NotificationDispatchManagerInstance {
        final static NotificationDispatchManager INSTANCE = new NotificationDispatchManager();
    }

    public static NotificationDispatchManager get() {
        return NotificationDispatchManagerInstance.INSTANCE;
    }

    private NotificationDispatchManager() {
        mCallbackList = new ArrayList<>();
        CompetitionStrategyDataManager.get().setRemoteCallbackList(mCallbackList);

        sceneCardCallbacks = new ArrayList<>();
        sceneCardCallbacksV2 = new ArrayList<>();
        CompetitionStrategyDataManager.get().setRemoteSceneCallbackList(sceneCardCallbacks);

        CompetitionStrategyDataManager.get().setRemoteSceneCallbackListV2(sceneCardCallbacksV2);

        HandlerThread handlerThread = new HandlerThread("NotificationDispatch");
        handlerThread.start();
        handler = new H(handlerThread.getLooper());
    }

    /**
     * 接收智能形象提示消息.
     * <p> 通知消息放到队列中 <br>
     *
     * @param notification {@link IStatusBarNotification} 通知数据
     * @since 1.0.0
     */
    public synchronized void dispatch(IStatusBarNotification notification) {
        Log.i(TAG, "launcher controller notification");
        Message msg = Message.obtain();
        msg.what = DISPATCH_NOTIFICATION;
        msg.obj = notification;
        handler.sendMessage(msg);
    }

    /**
     * 取消智能信息提示消息.
     * <p> 取消通知并把队列中的数据移除或通知触达层取消 <br>
     *
     * @param notification {@link IStatusBarNotification} 通知数据
     * @since 1.0.0
     */
    public synchronized void cancelNotification(IStatusBarNotification notification) {
        //取消参与竞合的通知
        Message msg = Message.obtain();
        msg.what = CANCEL_NOTIFICATION;
        msg.obj = notification;
        handler.sendMessage(msg);
    }

    /**
     * 接收智能卡片，智能提示消息.
     * <p> 智能卡片消息放入队列中 <br>
     *
     * @param iSceneCardInfo {@link ISceneCardInfoV2} 智能卡片消息数据
     * @since 1.0.0
     */
    public synchronized void dispatch(ISceneCardInfoV2 iSceneCardInfo) {
        Message msg = Message.obtain();
        msg.what = DISPATCH_SCENE_CARD;
        msg.obj = iSceneCardInfo;
        handler.sendMessage(msg);
    }

    /**
     * 取消智能卡片，智能提示消息.
     * <p> 取消通知并把队列中的数据移除或通知触达层取消 <br>
     *
     * @param iSceneCardInfo {@link ISceneCardInfoV2} 智能卡片消息数据
     * @since 1.0.0
     */
    public synchronized void removeSceneCard(ISceneCardInfoV2 iSceneCardInfo) {
        Message msg = Message.obtain();
        msg.what = CANCEL_SCENE_CARD;
        msg.obj = iSceneCardInfo;
        handler.sendMessage(msg);
    }

    /**
     * 注册形象智能提示.
     * <p> 客户端注册 callback<br>
     *
     * @param callback {@link ICardNotificationListener}
     * @since 1.0.0
     */
    public synchronized void register(ICardNotificationListener callback) {
        Log.i(TAG, "register card client " + callback);
        if (mCallbackList == null) {
            mCallbackList = new ArrayList<>();
        }
        mCallbackList.remove(callback);
        mCallbackList.add(callback);
    }

    /**
     * 解注册智能提示.
     * <p> 客户端解注册 callback<br>
     *
     * @param callback {@link ICardNotificationListener}
     * @since 1.0.0
     */
    public synchronized void unregister(ICardNotificationListener callback) {
        Log.i(TAG, "unregister card client " + callback);
        if (mCallbackList != null) {
            mCallbackList.remove(callback);
        }
    }

    /**
     * 注册智能卡片监听
     *
     * @param listener {@link ISceneCardListener}
     * @since 1.0.0
     */
    public synchronized void register(ISceneCardListener listener) {
        Log.i(TAG, "register scene client " + listener);
        if (sceneCardCallbacks == null) {
            sceneCardCallbacks = new ArrayList<>();
        }

        if (!sceneCardCallbacks.contains(listener)) {
            sceneCardCallbacks.add(listener);
        }
    }

    /**
     * 注册智能卡片监听
     *
     * @param listener {@link ISceneCardListenerV2}
     * @since 1.0.0
     */
    public synchronized void register(ISceneCardListenerV2 listener) {
        Log.i(TAG, "register scene client " + listener);
        if (sceneCardCallbacksV2 == null) {
            sceneCardCallbacksV2 = new ArrayList<>();
        }

        if (!sceneCardCallbacksV2.contains(listener)) {
            sceneCardCallbacksV2.add(listener);
        }
    }


    /**
     * 解注册智能卡片监听
     *
     * @param listener {@link ISceneCardListener}
     * @since 1.0.0
     */
    public synchronized void unregister(ISceneCardListener listener) {
        Log.i(TAG, "unregister scene client " + listener);
        if (sceneCardCallbacks != null) {
            sceneCardCallbacks.remove(listener);
        }
    }

    /**
     * 解注册智能卡片监听
     *
     * @param listener {@link ISceneCardListenerV2}
     * @since 1.0.0
     */
    public synchronized void unregister(ISceneCardListenerV2 listener) {
        Log.i(TAG, "unregister scene client " + listener);
        if (sceneCardCallbacksV2 != null) {
            sceneCardCallbacksV2.remove(listener);
        }
    }

    public void notifyCardHandleStatus(INotificationBar iNotificationBar, int status) {
        Log.i(TAG, "handle card status " + status);
        CompetitionStrategyDataManager.get().sendNotification(status);
    }

    /**
     * 智能卡片被用户处理监听
     * <p> 该方法如果接到的参数是 Constants.ISceneCardStatus.STATUS_DONE 则说明触达层需 LC 给其下发队列中的下一条消息<br>
     *
     * @param status {@link Constants}当前触达层智能卡片的处理状态
     * @since 1.0.0
     */
    public void notifySceneCardStatusChange(int status) {
        Log.i(TAG, "notifySceneCardStatusChange " + status);
        if (status == Constants.ISceneCardStatus.STATUS_DONE) {
            CompetitionStrategyDataManager.get().notifySceneCardStatusChange();
        }
    }

    /**
     * 接收场景物模型接口
     * <p> 解析场景引擎智能卡片数据<br>
     *
     * @param jsonStr 数据协议体
     * @return 智能卡片数据是否存在异常
     * @since 1.0.0
     */
    public int sendCardNotification(String jsonStr) {
        if (TextUtils.isEmpty(jsonStr)) {
            Log.w(TAG, "scene string is null");
            return MSG_ERROR;
        }
        try {
            PushMsgParser parser = PushMsgParser.newInstance(LauncherControllerApp.get(), jsonStr);
            ISceneCardInfoV2 iCardInfo = parser.convertSceneCardInfo(null, null);
            if (iCardInfo == null) {
                Log.e(TAG, "scene config error");
                return MSG_ERROR;
            }
            dispatch(iCardInfo);
            return MSG_OK;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return MSG_ERROR;
    }


    private static class H extends Handler {

        H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DISPATCH_NOTIFICATION:
                    Log.i(TAG, "enqueue notification.");
                    IStatusBarNotification notification = (IStatusBarNotification) msg.obj;
                    CompetitionStrategyDataManager.get().enqueueNotification(notification);
                    break;

                case CANCEL_NOTIFICATION:
                    Log.i(TAG, "cancel notification.");
                    notification = (IStatusBarNotification) msg.obj;
                    CompetitionStrategyDataManager.get().cancelNotification(notification);
                    break;

                case DISPATCH_SCENE_CARD:
                    Log.i(TAG, "send scene card");
                    ISceneCardInfoV2 iSceneCardInfo = (ISceneCardInfoV2) msg.obj;
                    CompetitionStrategyDataManager.get().enqueueSceneCard(iSceneCardInfo);
                    break;
                case CANCEL_SCENE_CARD:
                    Log.i(TAG, "cancel scene card");
                    iSceneCardInfo = (ISceneCardInfoV2) msg.obj;
                    CompetitionStrategyDataManager.get().removeSceneCard(iSceneCardInfo);
                    break;
                default:
                    break;
            }
        }
    }

}
